LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;

-------------------------------------- Forwarding_Prototype --------------------------------------------------
--
-- Inputs:
-- clk = The clock.
-- reset = The reset signal.
--
-- Outputs:
-- Everything
-- 
-- Stuff that still needs to be done is listed under each section of the actual code, and whatever else I 
-- forgot about. This is just to check that we have a control system that works. Once this is done, the only
-- inputs we should have to feed into this are the clock and a reset signal, and the engine will do the rest.

ENTITY Forwarding_Prototype IS
   
    PORT(
	   clk, reset								: IN STD_LOGIC
	   
	   --RCV Debug Signals
	   --debug_IN_FWD_to_RCV_LENGTH_ACK : OUT STD_LOGIC;
	   --debug_IN_FWD_to_RCV_FRAME_ACK : OUT STD_LOGIC;
	   --debug_OUT_RCV_to_FWD_DATA : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
	   --debug_OUT_RCV_to_FWD_LENGTH : OUT STD_LOGIC_VECTOR(11 DOWNTO 0);
	   --debug_OUT_RCV_FWD_FRAMEAVAILABLE : OUT STD_LOGIC;
	   
	   --TBL Debug Signals
	   --debug_IN_FWD_to_TBL_ACK : OUT STD_LOGIC;
	   --debug_IN_FWD_to_TBL_desAddress : OUT STD_LOGIC_VECTOR(47 DOWNTO 0);
	   --debug_IN_FWD_to_TBL_srcAddress : OUT STD_LOGIC_VECTOR(47 DOWNTO 0);
	   --debug_IN_FWD_to_TBL_srcPort : OUT STD_LOGIC_VECTOR(1 DOWNTO 0);
	   --debug_OUT_TBL_to_FWD_ACK : OUT STD_LOGIC;
	   --debug_OUT_TBL_to_FWD_Valid : OUT STD_LOGIC;
	   --debug_OUT_TBL_to_FWD_Port : OUt STD_LOGIC_VECTOR(2 DOWNTO 0);
	   
	   -- XMT Debug Signals
	   --debug_IN_FWD_to_XMT_ACK : OUT STD_LOGIC;
	   --debug_IN_FWD_to_XMT_DATA : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
	   --debug_IN_FWD_to_XMT_LENGTH : OUT STD_LOGIC_VECTOR(10 DOWNTO 0);
	   --debug_IN_FWD_to_XMT_DONE : OUT STD_LOGIC;
	   --debug_OUT_XMT_to_FWD_ACK : OUT STD_LOGIC;
	   --debug_OUT_XMT_FWD_spaceavailable : OUT STD_LOGIC_VECTOR(10 DOWNTO 0);
       
       );
       
END Forwarding_Prototype;

ARCHITECTURE fwd_proto_arch OF Forwarding_Prototype IS
   
-------------------------------------- Components ----------------------------------------------- 

-------------------------------------- Dummy_RCV --------------------------------------------------------

-- Details in the Dummy_RCV.vhd.

COMPONENT Dummy_RCV IS
   PORT(
	   clk, reset			  	  : IN STD_LOGIC;
	   IN_FWD_to_RCV_LENGTH_ACK	  : IN STD_LOGIC;
	   IN_FWD_to_RCV_FRAME_ACK	  : IN STD_LOGIC;
	   OUT_RCV_to_FWD_DATA	  	  : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
	   OUT_RCV_to_FWD_LENGTH  	  : OUT STD_LOGIC_VECTOR(11 DOWNTO 0);
	   OUT_RCV_to_FWD_FRAMEAVAILABLE : OUT STD_LOGIC
       );
END COMPONENT;

-------------------------------------- Dummy_TABLE ----------------------------------------------------------------

-- Details in Dummy_TABLE.vhd.

COMPONENT Dummy_TABLE IS
   PORT(
	   clk, reset			    : IN STD_LOGIC;
	   IN_FWD_to_TBL_ACK	    : IN STD_LOGIC;
	   IN_FWD_to_TBL_desAddress : IN STD_LOGIC_VECTOR(47 DOWNTO 0);
	   IN_FWD_to_TBL_srcAddress : IN STD_LOGIC_VECTOR(47 DOWNTO 0);
	   IN_FWD_to_TBL_srcPort	: IN STD_LOGIC_VECTOR(1 DOWNTO 0);
	   OUT_TBL_to_FWD_ACK		: OUT STD_LOGIC;
	   OUT_TBL_to_FWD_Valid		: OUT STD_LOGIC;
       OUT_TBL_to_FWD_Port	 	: OUT STD_LOGIC_VECTOR(2 DOWNTO 0)
       );
END COMPONENT;

-------------------------------------- Dummy_XMT ---------------------------------------------------

-- Details in Dummy_XMT.vhd.

COMPONENT Dummy_XMT IS
   PORT(
	   clk, reset			 	 	 : IN STD_LOGIC;
	   IN_FWD_to_XMT_ACK	 	 	 : IN STD_LOGIC;
	   IN_FWD_to_XMT_DATA	 	 	 : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
	   IN_FWD_to_XMT_LENGTH 	 	 : IN STD_LOGIC_VECTOR(10 DOWNTO 0);
	   IN_FWD_to_XMT_DONE		 	 : IN STD_LOGIC;
       OUT_XMT_to_FWD_ACK		 	 : OUT STD_LOGIC;
       OUT_XMT_to_FWD_spaceavailable : OUT STD_LOGIC_VECTOR(10 DOWNTO 0)
       );
END COMPONENT;

-------------------------------------- SaturatingCounter ----------------------------------------------
--
-- Inputs:
-- incount = A signal to increment the counter.
-- reset = The reset signal.
--
-- Outputs:
-- saturatedcount = The current number the counter has counted to.
--
-- We need those three counters to track stuff. These are 17 bits so that
-- the count_enable is controlled by a single comparison to a single pin 
-- instead of checking if all 16 pins are high. This works as long as the
-- first time it is incremented is more than 10 ns after the device is turned
-- on.

COMPONENT SaturatingCounter IS
   PORT(
	   incount, reset			 : IN STD_LOGIC;
       saturatedcount 		 	 : OUT STD_LOGIC_VECTOR(16 DOWNTO 0)
       );
END COMPONENT;

--------------------------------------- Buffer  ------------------------------------------------------

COMPONENT ForwardingBuffer IS
   PORT(
       send_data : IN STD_LOGIC;
       data_in : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
       recv_data : OUT STD_LOGIC;
       data_out : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
       srcAddressValid : OUT STD_LOGIC;
       desAddressValid : OUT STD_LOGIC;
       srcPort : OUT STD_LOGIC_VECTOR(1 DOWNTO 0);
       srcAddress : OUT STD_LOGIC_VECTOR(47 DOWNTO 0);
       desAddress : OUT STD_LOGIC_VECTOR(47 DOWNTO 0)
       );
END COMPONENT;

-------------------------------------- Arbiter  ------------------------------------------------------

COMPONENT Arbiter IS
   PORT(
       tableheardarbiter : IN STD_LOGIC;
	   srcAddressValid0, srcAddressValid1, srcAddressValid2, srcAddressValid3 : IN STD_LOGIC;
	   desAddressValid0, desAddressValid1, desAddressValid2, desAddressValid3 : IN STD_LOGIC;
	   portChoice : OUT STD_LOGIC_VECTOR(1 DOWNTO 0);
	   portReady : OUT STD_LOGIC -- Are any ports ready?
       );
END COMPONENT;

-------------------------------------- OutMUX   ------------------------------------------------------

COMPONENT OutMUX IS
   PORT(
       from_databuffer0 : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
       from_databuffer1 : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
       from_databuffer2 : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
       from_databuffer3 : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
       XMT_to_RCV_ACK : IN STD_LOGIC;
	   correct_Port : IN STD_LOGIC_VECTOR(2 DOWNTO 0);
	   portReady : IN STD_LOGIC;
	   toxmtbuffer : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
	   RCV_to_XMT_ACK : OUT STD_LOGIC
       );
END COMPONENT;


-------------------------------------- Signals  ------------------------------------------------------

-- COUNTERS
SIGNAL CountA, CountB, CountC : STD_LOGIC;
SIGNAL CounterA : STD_LOGIC_VECTOR(16 DOWNTO 0);
SIGNAL CounterB : STD_LOGIC_VECTOR(16 DOWNTO 0);
SIGNAL CounterC : STD_LOGIC_VECTOR(16 DOWNTO 0);

-- RECORDING
SIGNAL srcPort : STD_LOGIC_VECTOR(1 DOWNTO 0);

-- BUFFER0
SIGNAL buffer0send_data : STD_LOGIC;
SIGNAL buffer0data_in : STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL buffer0recv_data : STD_LOGIC;
SIGNAL buffer0data_out : STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL buffer0srcAddressValid : STD_LOGIC;
SIGNAL buffer0desAddressValid : STD_LOGIC;
SIGNAL buffer0srcPort : STD_LOGIC_VECTOR(1 DOWNTO 0);
SIGNAL buffer0srcAddress : STD_LOGIC_VECTOR(47 DOWNTO 0);
SIGNAL buffer0desAddress : STD_LOGIC_VECTOR(47 DOWNTO 0);

-- BUFFER1
SIGNAL buffer1send_data : STD_LOGIC;
SIGNAL buffer1data_in : STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL buffer1recv_data : STD_LOGIC;
SIGNAL buffer1data_out : STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL buffer1srcAddressValid : STD_LOGIC;
SIGNAL buffer1desAddressValid : STD_LOGIC;
SIGNAL buffer1srcPort : STD_LOGIC_VECTOR(1 DOWNTO 0);
SIGNAL buffer1srcAddress : STD_LOGIC_VECTOR(47 DOWNTO 0);
SIGNAL buffer1desAddress : STD_LOGIC_VECTOR(47 DOWNTO 0);

-- BUFFER2
SIGNAL buffer2send_data : STD_LOGIC;
SIGNAL buffer2data_in : STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL buffer2recv_data : STD_LOGIC;
SIGNAL buffer2data_out : STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL buffer2srcAddressValid : STD_LOGIC;
SIGNAL buffer2desAddressValid : STD_LOGIC;
SIGNAL buffer2srcPort : STD_LOGIC_VECTOR(1 DOWNTO 0);
SIGNAL buffer2srcAddress : STD_LOGIC_VECTOR(47 DOWNTO 0);
SIGNAL buffer2desAddress : STD_LOGIC_VECTOR(47 DOWNTO 0);

-- BUFFER3
SIGNAL buffer3send_data : STD_LOGIC;
SIGNAL buffer3data_in : STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL buffer3recv_data : STD_LOGIC;
SIGNAL buffer3data_out : STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL buffer3srcAddressValid : STD_LOGIC;
SIGNAL buffer3desAddressValid : STD_LOGIC;
SIGNAL buffer3srcPort : STD_LOGIC_VECTOR(1 DOWNTO 0);
SIGNAL buffer3srcAddress : STD_LOGIC_VECTOR(47 DOWNTO 0);
SIGNAL buffer3desAddress : STD_LOGIC_VECTOR(47 DOWNTO 0);

-- ARBITRATION
SIGNAL srcAddress0Valid : STD_LOGIC;
SIGNAL desAddress0Valid : STD_LOGIC;
SIGNAL srcAddress1Valid : STD_LOGIC;
SIGNAL desAddress1Valid : STD_LOGIC;
SIGNAL srcAddress2Valid : STD_LOGIC;
SIGNAL desAddress2Valid : STD_LOGIC;
SIGNAL srcAddress3Valid : STD_LOGIC;
SIGNAL desAddress3Valid : STD_LOGIC;
SIGNAL arbiterPortChoice : STD_LOGIC_VECTOR(1 DOWNTO 0);
SIGNAL arbiterPortReady : STD_LOGIC;

-- RCV0
SIGNAL FWD_to_RCV0_LENGTH_ACK, FWD_to_RCV0_FRAME_ACK : STD_LOGIC;
SIGNAL RCV0_to_FWD_DATA	: STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL RCV0_to_FWD_LENGTH : STD_LOGIC_VECTOR(11 DOWNTO 0);
SIGNAL RCV0_to_FWD_FRAMEAVAILABLE : STD_LOGIC;

-- RCV1
SIGNAL FWD_to_RCV1_LENGTH_ACK, FWD_to_RCV1_FRAME_ACK : STD_LOGIC;
SIGNAL RCV1_to_FWD_DATA	: STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL RCV1_to_FWD_LENGTH : STD_LOGIC_VECTOR(11 DOWNTO 0);
SIGNAL RCV1_to_FWD_FRAMEAVAILABLE : STD_LOGIC;

-- RCV2
SIGNAL FWD_to_RCV2_LENGTH_ACK, FWD_to_RCV2_FRAME_ACK : STD_LOGIC;
SIGNAL RCV2_to_FWD_DATA	: STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL RCV2_to_FWD_LENGTH : STD_LOGIC_VECTOR(11 DOWNTO 0);
SIGNAL RCV2_to_FWD_FRAMEAVAILABLE : STD_LOGIC;

-- RCV3
SIGNAL FWD_to_RCV3_LENGTH_ACK, FWD_to_RCV3_FRAME_ACK : STD_LOGIC;
SIGNAL RCV3_to_FWD_DATA	: STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL RCV3_to_FWD_LENGTH : STD_LOGIC_VECTOR(11 DOWNTO 0);
SIGNAL RCV3_to_FWD_FRAMEAVAILABLE : STD_LOGIC;

-- TBL
SIGNAL FWD_to_TBL_ACK : STD_LOGIC;
SIGNAL FWD_to_TBL_desAddress : STD_LOGIC_VECTOR(47 DOWNTO 0);
SIGNAL FWD_to_TBL_srcAddress : STD_LOGIC_VECTOR(47 DOWNTO 0);
SIGNAL FWD_to_TBL_srcPort : STD_LOGIC_VECTOR(1 DOWNTO 0);
SIGNAL TBL_to_FWD_ACK : STD_LOGIC;
SIGNAL TBL_to_FWD_Valid : STD_LOGIC;
SIGNAL TBL_to_FWD_Port : STD_LOGIC_VECTOR(2 DOWNTO 0);

-- XMT0
SIGNAL FWD_to_XMT0_ACK : STD_LOGIC;
SIGNAL FWD_to_XMT0_DATA : STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL FWD_to_XMT0_LENGTH : STD_LOGIC_VECTOR(10 DOWNTO 0);
SIGNAL FWD_to_XMT0_DONE : STD_LOGIC;
SIGNAL XMT0_to_FWD_ACK : STD_LOGIC;
SIGNAL XMT0_to_FWD_spaceavailable : STD_LOGIC_VECTOR(10 DOWNTO 0);

-- XMT1
SIGNAL FWD_to_XMT1_ACK : STD_LOGIC;
SIGNAL FWD_to_XMT1_DATA : STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL FWD_to_XMT1_LENGTH : STD_LOGIC_VECTOR(10 DOWNTO 0);
SIGNAL FWD_to_XMT1_DONE : STD_LOGIC;
SIGNAL XMT1_to_FWD_ACK : STD_LOGIC;
SIGNAL XMT1_to_FWD_spaceavailable : STD_LOGIC_VECTOR(10 DOWNTO 0);

-- XMT2
SIGNAL FWD_to_XMT2_ACK : STD_LOGIC;
SIGNAL FWD_to_XMT2_DATA : STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL FWD_to_XMT2_LENGTH : STD_LOGIC_VECTOR(10 DOWNTO 0);
SIGNAL FWD_to_XMT2_DONE : STD_LOGIC;
SIGNAL XMT2_to_FWD_ACK : STD_LOGIC;
SIGNAL XMT2_to_FWD_spaceavailable : STD_LOGIC_VECTOR(10 DOWNTO 0);

-- XMT3
SIGNAL FWD_to_XMT3_ACK : STD_LOGIC;
SIGNAL FWD_to_XMT3_DATA : STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL FWD_to_XMT3_LENGTH : STD_LOGIC_VECTOR(10 DOWNTO 0);
SIGNAL FWD_to_XMT3_DONE : STD_LOGIC;
SIGNAL XMT3_to_FWD_ACK : STD_LOGIC;
SIGNAL XMT3_to_FWD_spaceavailable : STD_LOGIC_VECTOR(10 DOWNTO 0);

-------------------------------------- The Actual Code -----------------------------------------------

BEGIN

-------------------------------------- Interface with RCV team ---------------------------------------

DummyRCV0Stage: Dummy_RCV PORT MAP (clk, reset, FWD_to_RCV0_LENGTH_ACK, FWD_to_RCV0_FRAME_ACK, RCV0_to_FWD_DATA, RCV0_to_FWD_LENGTH, RCV0_to_FWD_FRAMEAVAILABLE);
DummyRCV1Stage: Dummy_RCV PORT MAP (clk, reset, FWD_to_RCV1_LENGTH_ACK, FWD_to_RCV1_FRAME_ACK, RCV1_to_FWD_DATA, RCV1_to_FWD_LENGTH, RCV1_to_FWD_FRAMEAVAILABLE);
DummyRCV2Stage: Dummy_RCV PORT MAP (clk, reset, FWD_to_RCV2_LENGTH_ACK, FWD_to_RCV2_FRAME_ACK, RCV2_to_FWD_DATA, RCV2_to_FWD_LENGTH, RCV2_to_FWD_FRAMEAVAILABLE);
DummyRCV3Stage: Dummy_RCV PORT MAP (clk, reset, FWD_to_RCV3_LENGTH_ACK, FWD_to_RCV3_FRAME_ACK, RCV3_to_FWD_DATA, RCV3_to_FWD_LENGTH, RCV3_to_FWD_FRAMEAVAILABLE);

-- Before I reach the TABLE bit, I need to keep moving the input data from RCV into a buffer, 
-- while making sure that I only add information to the buffer if the transfer is complete.
-- Once the transfer is complete we can send stuff to the table group OR we can send the table
-- group where the current packet is from and where it wants to go.

-- What still needs to be done:
-- 1.) Actually implement our buffers to hold data from RCV.
-- 2.) Detect when we have enough room to hold all the data being sent to us and telling RCV when
-- there's going to be a problem.

----------------------------------------------- Buffering ---------------------------------------------

-- Take a variable length input from RCV and store it in a long sequence of buffers. Parse the source address
-- and destination address from the input as it passes into the buffer.

Buffer0Stage: ForwardingBuffer PORT MAP (buffer0send_data, RCV0_to_FWD_DATA, buffer0recv_data, buffer0data_out, buffer0srcAddressValid, buffer0desAddressValid, buffer0srcPort, buffer0srcAddress, buffer0desAddress);
Buffer1Stage: ForwardingBuffer PORT MAP (buffer1send_data, RCV1_to_FWD_DATA, buffer1recv_data, buffer1data_out, buffer1srcAddressValid, buffer1desAddressValid, buffer1srcPort, buffer1srcAddress, buffer1desAddress);
Buffer2Stage: ForwardingBuffer PORT MAP (buffer2send_data, RCV2_to_FWD_DATA, buffer2recv_data, buffer2data_out, buffer2srcAddressValid, buffer2desAddressValid, buffer2srcPort, buffer2srcAddress, buffer2desAddress);
Buffer3Stage: ForwardingBuffer PORT MAP (buffer3send_data, RCV3_to_FWD_DATA, buffer3recv_data, buffer3data_out, buffer3srcAddressValid, buffer3desAddressValid, buffer3srcPort, buffer3srcAddress, buffer3desAddress);


-----------------------------------------------  Arbiter  ---------------------------------------------

-- Asynchronously choose between four inputs. (Just straight-up logic.)

ArbiterStage: Arbiter PORT MAP (TBL_to_FWD_ACK, srcAddress0Valid, srcAddress1Valid, srcAddress2Valid, srcAddress3Valid, desAddress0Valid, desAddress1Valid, desAddress2Valid, desAddress3Valid, arbiterPortChoice, arbiterPortReady);


-----------------------------------------------     MUX 1    ---------------------------------------------

-- Connect stuff from Arbiter and the buffers to the table interface. Move values from buffers to the signals
-- being passed to the table.

-------------------------------------- Interface with TABLE team ---------------------------------------

DummyTABLEStage: Dummy_TABLE PORT MAP (clk, reset, arbiterPortReady, FWD_to_TBL_desAddress, FWD_to_TBL_srcAddress, FWD_to_TBL_srcPort, TBL_to_FWD_ACK, TBL_to_FWD_Valid, TBL_to_FWD_Port);

-- Right now TABLE can return in a variable number of cycles and we'll still work correctly. We'll
-- stall until the port number returns, but there's not much we can actually do about that. We can
-- send the address earlier, build our own cache, or try to speculatively do stuff, but stalling is
-- probably the way to go to begin with.
-- What still needs to be done:
-- 1.) Actually send the data to our dummy table.
-- 2.) Implement some control logic that makes us wait until table response before ACK-ing XMT.
-- 3.) See if we can send information to Table while we're still receiving data from RCV.

-----------------------------------------------     MUX 2    ---------------------------------------------

-- Connect stuff from Table and the buffers to the XMT interface. Move values from buffers to the signals
-- being passed to XMT. Supervise transmission of data to XMT (Check that we're receiving 1s back from XMT).

DeMux0Stage: OutMUX PORT MAP (buffer0data_out, buffer1data_out, buffer2data_out, buffer3data_out, XMT0_to_FWD_ACK, TBL_to_FWD_Port, TBL_to_FWD_Valid, FWD_to_XMT0_DATA, FWD_to_XMT0_ACK);
DeMux1Stage: OutMUX PORT MAP (buffer0data_out, buffer1data_out, buffer2data_out, buffer3data_out, XMT1_to_FWD_ACK, TBL_to_FWD_Port, TBL_to_FWD_Valid, FWD_to_XMT1_DATA, FWD_to_XMT1_ACK);
DeMux2Stage: OutMUX PORT MAP (buffer0data_out, buffer1data_out, buffer2data_out, buffer3data_out, XMT2_to_FWD_ACK, TBL_to_FWD_Port, TBL_to_FWD_Valid, FWD_to_XMT2_DATA, FWD_to_XMT2_ACK);
DeMux3Stage: OutMUX PORT MAP (buffer0data_out, buffer1data_out, buffer2data_out, buffer3data_out, XMT3_to_FWD_ACK, TBL_to_FWD_Port, TBL_to_FWD_Valid, FWD_to_XMT3_DATA, FWD_to_XMT3_ACK);


--------------------------------------  Interface with the XMT team -------------------------------------

DummyXMT0Stage: Dummy_XMT PORT MAP (clk, reset, FWD_to_XMT0_ACK, FWD_to_XMT0_DATA, FWD_to_XMT0_LENGTH, FWD_to_XMT0_DONE, XMT0_to_FWD_ACK, XMT0_to_FWD_spaceavailable);
DummyXMT1Stage: Dummy_XMT PORT MAP (clk, reset, FWD_to_XMT1_ACK, FWD_to_XMT1_DATA, FWD_to_XMT1_LENGTH, FWD_to_XMT1_DONE, XMT1_to_FWD_ACK, XMT1_to_FWD_spaceavailable);
DummyXMT2Stage: Dummy_XMT PORT MAP (clk, reset, FWD_to_XMT2_ACK, FWD_to_XMT2_DATA, FWD_to_XMT2_LENGTH, FWD_to_XMT2_DONE, XMT2_to_FWD_ACK, XMT2_to_FWD_spaceavailable);
DummyXMT3Stage: Dummy_XMT PORT MAP (clk, reset, FWD_to_XMT3_ACK, FWD_to_XMT3_DATA, FWD_to_XMT3_LENGTH, FWD_to_XMT3_DONE, XMT3_to_FWD_ACK, XMT3_to_FWD_spaceavailable);

-- We need to define some kind of device to poll XMT and see when they're done before we start sending them
-- all of our data. By the time we actually do useful stuff with Dummy_XMT, we have a port number (which doesn't
-- do anything in this prototype because we're only dealing with a single input and output port), a large buffer of
-- data, 16 bits holding our data size, and a large buffer holding all of our data. All we have to do is:
-- 1.) Write a procedure to poll XMT until they respond
-- 2.) Send them our data until we run out, at which point we send them another ACK to tell them we're done.
-- 3.) Also implement some means of logic to have the port number of table actually have something to do with
-- something.

--------------------------------------  Counters ----------------------------------------------------------

IncrementCounterAStage: SaturatingCounter PORT MAP (CountA, reset, CounterA);
IncrementCounterBStage: SaturatingCounter PORT MAP (CountB, reset, CounterA);
IncrementCounterCStage: SaturatingCounter PORT MAP (CountC, reset, CounterA);

-- I don't remember what we're counting but I know we need to count three things. All we have to do is change how
-- CountA, CountB, and CountC get triggered everytime a page successfully goes to XMT and this'll work. (I have 
-- waveforms verifying it: SaturatingCounterWorks.png and SaturatingCounterWorks2.png).

END fwd_proto_arch;